#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Filename: create_ticket.py

##
# Módulos del sistema
# Parte gráfica
try:
    import pygtk
    pygtk.require("2.0")
    import gtk
    import gtk.glade
except ImportError, error:
    print error
    print "Necesitas la librería gráficas gtk+pygtk"

##
# Utilidades
import os
from datetime import datetime

##
# Módulos propios
try:
    from lib.database import Empleado, Clasificacion, GrupoDeResolucion
except ImportError, error:
    print error
    print "Problemas con la BD en: '/gui/create_ticket.py'"
try:
    from lib.config import WIDTH, HEIGHT
    from gui.msj_retroalimentacion import MensajeDeAdvertencia, MensajeDeError
    from gui.msj_retroalimentacion import MensajeDeNotificacion
    from lib.funciones_utiles import close, add_find_column
except ImportError, error:
    print error
    print "No se pudo cargar el archivo (create_ticket.py)"

class CreateTicket:
    """Crear ticket.

    Clase que permitira el manejo de la interfaz de creación de ticket.
    Utilizado en el CDU-01 Registrar Ticket

    """
    def __init__(self, padre, usuario_logueado, nro_ticket, pagina):
        
        self.padre = padre
        self.caja_entrada = None
        self.caja_label = None
        self.caja_observaciones = None
        self.caja_botonera = None 
        self.entry_legajo_empleado = None 
        self.entry_apellido_empleado = None
        self.entry_nombre_empleado = None
        self.entry_codigo_clasificacion = None
        self.entry_nombre_clasificacion = None
        self.entry_descripcion = None
        self.descripcion=None
        self.inicializar(pagina, nro_ticket)
        self.entry_legajo_empleado.grab_focus()
        self.limpiar_campos()
        # Requerimiento especial del CDU. Con <Enter> pasamos de entry
        self.conect_entry_enter()
        # Variables necesarias para registrar ticket   
        self.empleado_solicitante = None 
        self.usuario_logueado = usuario_logueado
        self.nro_ticket = nro_ticket
    
    def inicializar(self, pagina, nro_ticket):
        """Cargara en las variables de instancia los widget correspondientes"""
        diccionario = {0: 'self.inicializar_pagina_cero',
                1: 'self.inicializar_pagina_uno',
                2: 'self.inicializar_pagina_dos',
                3: 'self.inicializar_pagina_tres'}
        
        funcion = diccionario.get(pagina)
        print funcion
        if funcion:
            eval(funcion)(nro_ticket)

    def inicializar_pagina_cero(self, nro_ticket):
        """
        """
        print "La página numero cero de crear ticket fue instanciada"
        # Varibles de instancia
        self.caja_entrada = self.padre.wTree.get_widget("hbox41")
        self.caja_label = self.padre.wTree.get_widget("hbox53")
        self.caja_observaciones = self.padre.wTree.get_widget("hbox58")
        self.caja_botonera = self.padre.wTree.get_widget("hbox68")
        self.caja_derivacion = self.padre.wTree.get_widget("vbox55")
        self.entry_legajo_empleado = self.padre.wTree.get_widget("entry11")
        self.entry_apellido_empleado = self.padre.wTree.get_widget("entry12")
        self.entry_nombre_empleado = self.padre.wTree.get_widget("entry13")
        self.entry_codigo_clasificacion = self.padre.wTree.get_widget("entry14")
        self.entry_nombre_clasificacion = self.padre.wTree.get_widget("entry15")
        self.entry_descripcion = self.padre.wTree.get_widget("textview28")
        self.descripcion = self.padre.wTree.get_widget("textview29")
        self.observaciones = self.padre.wTree.get_widget("textview30")
        self.tree_resultado = self.padre.wTree.get_widget("treeview16")
        # Label's para el segundo formulario
        self.label_legajo = self.padre.wTree.get_widget("legajo_cliente2")
        self.label_apellido = self.padre.wTree.get_widget("apellido_cliente2")
        self.label_nombre = self.padre.wTree.get_widget("nombre_cliente2")
        self.label_codigo =  self.padre.wTree.get_widget("codigo_clasificacion2")
        self.label_clasificacion = self.padre.wTree.get_widget("nombre_clasificacion2")
        self.label_numero = self.padre.wTree.get_widget("numero_ticket2")
        self.label_fecha = self.padre.wTree.get_widget("label298")
        self.label_hora = self.padre.wTree.get_widget("label299")
        # Escondemos y mostramos
        self.caja_entrada.show()
        self.caja_label.hide()
        self.caja_observaciones.hide()
        self.fecha_creacion = datetime.now()
        self.fecha, self.hora = self.fecha_creacion.strftime("%d-%m-%Y %H:%M:%S").split()
        self.padre.wTree.get_widget("label_fecha_apertura2").set_text(self.fecha)
        self.padre.wTree.get_widget("label_hora_apertura2").set_text(self.hora)
        self.padre.wTree.get_widget("label_numero_ticket2").set_text(str(nro_ticket))
    
    def inicializar_pagina_uno(self, nro_ticket):
        """
        """
        print "La página numero uno de crear ticket fue instanciada"
        # Varibles de instancia
        # Formulario de entrada
        self.caja_entrada = self.padre.wTree.get_widget("hbox71")
        self.caja_label = self.padre.wTree.get_widget("hbox77")
        self.caja_observaciones = self.padre.wTree.get_widget("hbox83")
        self.caja_botonera = self.padre.wTree.get_widget("hbox88")
        self.caja_derivacion = self.padre.wTree.get_widget("vbox87")
        self.entry_legajo_empleado = self.padre.wTree.get_widget("entry19")
        self.entry_apellido_empleado = self.padre.wTree.get_widget("entry22")
        self.entry_nombre_empleado = self.padre.wTree.get_widget("entry25")
        self.entry_codigo_clasificacion = self.padre.wTree.get_widget("entry26")
        self.entry_nombre_clasificacion = self.padre.wTree.get_widget("entry27")
        self.entry_descripcion = self.padre.wTree.get_widget("textview31")
        self.descripcion = self.padre.wTree.get_widget("textview32")
        self.observaciones = self.padre.wTree.get_widget("textview33")
        self.tree_resultado = self.padre.wTree.get_widget("treeview23")
        # Label's para el segundo formulario
        self.label_legajo = self.padre.wTree.get_widget("legajo_cliente3")
        self.label_apellido = self.padre.wTree.get_widget("apellido_cliente3")
        self.label_nombre = self.padre.wTree.get_widget("nombre_cliente3")
        self.label_codigo =  self.padre.wTree.get_widget("codigo_clasificacion3")
        self.label_clasificacion = self.padre.wTree.get_widget("nombre_clasificacion3")
        self.label_numero = self.padre.wTree.get_widget("numero_ticket3")
        self.label_fecha = self.padre.wTree.get_widget("label419")
        self.label_hora = self.padre.wTree.get_widget("label420")
        # Escondemos y mostramos
        self.caja_entrada.show()
        self.caja_label.hide()
        self.caja_observaciones.hide()
        self.fecha_creacion = datetime.now()
        self.fecha, self.hora = self.fecha_creacion.strftime("%d-%m-%Y %H:%M:%S").split()
        self.padre.wTree.get_widget("label_fecha_apertura3").set_text(self.fecha)
        self.padre.wTree.get_widget("label_hora_apertura3").set_text(self.hora)
        self.padre.wTree.get_widget("label_numero_ticket3").set_text(str(nro_ticket))
    
    def inicializar_pagina_dos(self, nro_ticket):
        """Manejara el tercer ticket"""
        print "La pagina tres de crear ticket fue creada"
        # Varibles de instancia
        # Formulario de entrada
        self.caja_entrada = self.padre.wTree.get_widget("hbox98")
        self.caja_label = self.padre.wTree.get_widget("hbox99")
        self.caja_observaciones = self.padre.wTree.get_widget("hbox107")
        self.caja_botonera = self.padre.wTree.get_widget("hbox142")
        self.caja_derivacion = self.padre.wTree.get_widget("vbox124")
        self.entry_legajo_empleado = self.padre.wTree.get_widget("entry28")
        self.entry_apellido_empleado = self.padre.wTree.get_widget("entry29")
        self.entry_nombre_empleado = self.padre.wTree.get_widget("entry30")
        self.entry_codigo_clasificacion = self.padre.wTree.get_widget("entry31")
        self.entry_nombre_clasificacion = self.padre.wTree.get_widget("entry37")
        self.entry_descripcion = self.padre.wTree.get_widget("textview34")
        self.descripcion = self.padre.wTree.get_widget("textview35")
        self.observaciones = self.padre.wTree.get_widget("textview36")
        self.tree_resultado = self.padre.wTree.get_widget("treeview42")
        # Label's para el segundo formulario
        self.label_legajo = self.padre.wTree.get_widget("legajo_cliente4")
        self.label_apellido = self.padre.wTree.get_widget("apellido_cliente4")
        self.label_nombre = self.padre.wTree.get_widget("nombre_cliente4")
        self.label_codigo =  self.padre.wTree.get_widget("codigo_clasificacion4")
        self.label_clasificacion = self.padre.wTree.get_widget("nombre_clasificacion4")
        self.label_numero = self.padre.wTree.get_widget("numero_ticket4")
        self.label_fecha = self.padre.wTree.get_widget("label531")
        self.label_hora = self.padre.wTree.get_widget("label532")
        # Escondemos y mostramos
        self.caja_entrada.show()
        self.caja_label.hide()
        self.caja_observaciones.hide()
        self.fecha_creacion = datetime.now()
        self.fecha, self.hora = self.fecha_creacion.strftime("%d-%m-%Y %H:%M:%S").split()
        self.padre.wTree.get_widget("label_fecha_apertura4").set_text(self.fecha)
        self.padre.wTree.get_widget("label_hora_apertura4").set_text(self.hora)
        self.padre.wTree.get_widget("label_numero_ticket4").set_text(str(nro_ticket))
    
    def inicializar_pagina_tres(self, nro_ticket):
        """4 ticket paralelo"""
        # Varibles de instancia
        # Formulario de entrada
        self.caja_entrada = self.padre.wTree.get_widget("hbox145")
        self.caja_label = self.padre.wTree.get_widget("hbox146")
        self.caja_observaciones = self.padre.wTree.get_widget("hbox148")
        self.caja_botonera = self.padre.wTree.get_widget("hbox155")
        self.caja_derivacion = self.padre.wTree.get_widget("vbox130")
        self.entry_legajo_empleado = self.padre.wTree.get_widget("entry55")
        self.entry_apellido_empleado = self.padre.wTree.get_widget("entry63")
        self.entry_nombre_empleado = self.padre.wTree.get_widget("entry64")
        self.entry_codigo_clasificacion = self.padre.wTree.get_widget("entry65")
        self.entry_nombre_clasificacion = self.padre.wTree.get_widget("entry66")
        self.entry_descripcion = self.padre.wTree.get_widget("textview37")
        self.descripcion = self.padre.wTree.get_widget("textview38")
        self.observaciones = self.padre.wTree.get_widget("textview39")
        self.tree_resultado = self.padre.wTree.get_widget("treeview43")
        # Label's para el segundo formulario
        self.label_legajo = self.padre.wTree.get_widget("legajo_cliente5")
        self.label_apellido = self.padre.wTree.get_widget("apellido_cliente5")
        self.label_nombre = self.padre.wTree.get_widget("nombre_cliente5")
        self.label_codigo =  self.padre.wTree.get_widget("codigo_clasificacion5")
        self.label_clasificacion = self.padre.wTree.get_widget("nombre_clasificacion5")
        self.label_numero = self.padre.wTree.get_widget("numero_ticket5")
        self.label_fecha = self.padre.wTree.get_widget("label618")
        self.label_hora = self.padre.wTree.get_widget("label619")
        # Escondemos y mostramos
        self.caja_entrada.show()
        self.caja_label.hide()
        self.caja_observaciones.hide()
        self.fecha_creacion = datetime.now()
        self.fecha, self.hora = self.fecha_creacion.strftime("%d-%m-%Y %H:%M:%S").split()
        self.padre.wTree.get_widget("label_fecha_apertura5").set_text(self.fecha)
        self.padre.wTree.get_widget("label_hora_apertura5").set_text(self.hora)
        self.padre.wTree.get_widget("label_numero_ticket5").set_text(str(nro_ticket))


    def contenedor(self):
        return self.padre.wTree.get_widget("vbox43")

    def conect_entry_enter(self):
        """Permite generar the activate signal para los widget"""
        def grab_focus(widget, other):
            other.grab_focus()
            self.completar_campos()

        def groups(lista, n, step=1):
            for index in xrange(0, len(lista)-(n-1), step):
                yield lista[index:index+n]

        path =(self.entry_legajo_empleado,
                self.entry_apellido_empleado,
                self.entry_nombre_empleado,
                self.entry_codigo_clasificacion,
                self.entry_nombre_clasificacion,
                self.entry_descripcion)

        for from0, to in groups(path, 2):
            from0.connect("activate", grab_focus, to)

    def completar_campos(self):
        """Completará los campos de entrada.

        Busca en la base de datos el nombre y apellido del Empleado con legago
        "nro_legajo" y la Clasificación con "nro_clasificacion", y los muestro
        en los campos correspondientes luedo de presionar <Enter> desde la
        funcion conect_entry_enter.

        Keyword arguments:
        None
        """
        nro_legajo = self.entry_legajo_empleado.get_text()
        nro_clasificacion = self.entry_codigo_clasificacion.get_text()

        if nro_legajo != '':
            # Levantar el apellido y nombre con este legajo
            consulta = Empleado.selectBy(legajo = nro_legajo)
            try:
                empleado = consulta[0]
                self.entry_apellido_empleado.set_text(empleado.apellido)
                self.entry_nombre_empleado.set_text(empleado.nombre)
                self.empleado_solicitante = empleado
                self.entry_codigo_clasificacion.grab_focus()
            except IndexError, error:
                print error
                msj = "Nro. de legajo inexistente en el Sistema de Personal."
                print msj
                msj_error = MensajeDeError(msj, self.padre.window)
                msj_error.run()
                self.entry_legajo_empleado.set_text('')
                self.entry_legajo_empleado.grab_focus()
        if nro_clasificacion !='':
            # Levantar el nombre de este codigo de clasificacion
            consulta = Clasificacion.selectBy(id = nro_clasificacion)
            try:
                clasificacion = consulta[0]
                self.entry_nombre_clasificacion.set_text(clasificacion.nombre)
                self.clasificacion_problema = clasificacion
                self.entry_descripcion.grab_focus()
            except IndexError, error:
                print error
                msj = "Codigo de clasificacion inexistente en el Sistema."
                print msj
                msj_error = MensajeDeError(msj, self.padre.window)
                msj_error.run()
                self.entry_codigo_clasificacion.set_text('')
        if (nro_legajo == '' and
                self.entry_apellido_empleado.get_text() !='' and
                self.entry_nombre_empleado.get_text()):
            consulta = Empleado.selectBy(
                    apellido = self.entry_apellido_empleado.get_text(),
                    nombre = self.entry_nombre_empleado.get_text())
            try:
                empleado = consulta[0]
                entry_legajo_empleado.set_text(empleado.legajo)
                self.empleado_solicitante = empleado
                print self.empleado_solicitante
            except IndexError, error:
                print error
                msj = "Empleado inexistente en el Sistema de Personal."
                msj_error = MensajeDeError(msj, self.padre.window)
                msj_error.run()
                self.entry_legajo_empleado.set_text('')
                self.entry_apellido_empleado.set_text('')
                self.entry_nombre_empleado.set_text('')
                self.entry_legajo_empleado.grab_focus()

    def run(self):
        #self.w_create_ticket = self.padre.wTree.get_widget("create_ticket")
        #gtk.main()
        pass

    def datos_no_validos(self):
        """Valida los datos de entrada para CREAR TICKET.

        Comprueba todos lo campos obligatorios necesarios para completar esta
        actividad, ellos son:
        -Legajo
        -Clasificacion
        -Descripcion del problema-

        Keyword arguments:
        None
        """
        if (self.entry_legajo_empleado.get_text() == "" or
               self.entry_codigo_clasificacion.get_text() == "" or
               self.texto_descripcion == "" ):
            #Caso 1
            error = "- Legajo\n- Clasificacion\n- Observaciones\n No pueden ser nulos"
            return True, error
        else:
            #Caso2:
            return False, ""

    def volver_al_estado_inicial(self):
        """Llamará a limpiar campos, y volverá las 'cajas' a su estado
        inicial"""
        self.limpiar_campos()
        self.caja_entrada.show()
        self.caja_label.hide()
        self.caja_observaciones.hide()
   
    def validate_create_ticket(self, widget=None):
        """Llama a datos_no_validos.

        Dependiendo de lo que retorna datos_no_validos mostrará la informacion
        necesaria para la proxima actividad -cerrar ó derivar-

        Keyword arguments:
        widget -- Widget de crear ticket

        """
        descripcion = self.entry_descripcion.get_buffer()
        start = descripcion.get_start_iter()
        end = descripcion.get_end_iter()
        self.texto_descripcion = descripcion.get_text(start,end)

        datos_no_validos,error = self.datos_no_validos()
        if datos_no_validos:
            msj_error = MensajeDeError(error, self.padre.window)
            msj_error.run()
        else:
            # Sistema registra el ticket como "abierto en mesa de ayuda"
            self.ticket = self.padre.mesa_de_ayuda.crear_ticket(
                            self.padre.usuario_logueado,
                            self.empleado_solicitante,
                            self.clasificacion_problema,
                            self.texto_descripcion,
                            self.fecha_creacion,
                            self.nro_ticket)
            self.caja_entrada.hide()
            # Se deben mostrar en el hbox64 los datos que pide la
            # especificacion del caso de uso nro_1
            self.label_legajo.set_text(self.empleado_solicitante.legajo)
            self.label_apellido.set_text(self.empleado_solicitante.apellido)
            self.label_nombre.set_text(self.empleado_solicitante.nombre)
            self.label_codigo.set_text(str(self.clasificacion_problema.id))
            self.label_clasificacion.set_text(self.clasificacion_problema.nombre)
            self.label_numero.set_text(str(self.nro_ticket))
            self.descripcion.get_buffer().set_text(self.texto_descripcion)
            self.label_fecha.set_text(self.fecha)
            self.label_hora.set_text(self.hora)
            self.caja_observaciones.show()
            self.observaciones.grab_focus()
            self.caja_label.show()

    def derivar_ticket(self, widget=None):
        """Deriva el ticket al grupo de resolucion que selecciona el usuario.

        Tenemos que validar observacion y ademas hacer hbox49 show() que ahí se
        encuentra la informacion de los grupos de resolucion. Datos necesarios
        para la derivacion de ticket.

        """
        self.caja_derivacion.show()
        self.caja_botonera.hide()
        self.obs, bandera = self.observacion_valida()
        if bandera:
            self.armar_lista_de_grupos()

    def validate_derivar_ticket(self, widget=None):
        """
        """
        grupo, seleccionado = self.un_grupo_seleccionado()
        if seleccionado:
            texto = "¿Está seguro que desea derivar el reclamo?"
            msj = MensajeDeAdvertencia(texto, self.padre.window)
            if msj.msj.run() == gtk.RESPONSE_YES:
                # Derivamos ticket
                fecha_derivacion = datetime.now()

                self.padre.mesa_de_ayuda.derivar_ticket(self.lista_grupos[grupo],
                        fecha_derivacion,
                        self.obs,
                        self.padre.usuario_logueado,
                        self.ticket)
                self.padre.wTree.get_widget("hbox41").hide()
                self.padre.wTree.get_widget("hbox53").hide()
                self.padre.wTree.get_widget("hbox58").hide()
                self.limpiar_campos()
                msj.msj.destroy()
                texto = "El ticket se derivo con éxito"
                notificacion = MensajeDeNotificacion(texto, self.padre.window)
                if notificacion.msj.run() == -5:
                    notificacion.msj.destroy()
                return True
            else:
                msj.msj.destroy()
        else:
            texto = "Debe seleccionar el Grupo al cual se derivará el ticket."
            msj = MensajeDeError(texto, self.padre.window)
            msj.run()
            return False

    def un_grupo_seleccionado(self):
        """Permite comprobar si selecciono un grupo de la lista.


        """
        model, path = self.tree_resultado.get_selection().get_selected_rows()
        if path:
            pos, = path[0]
            return pos, True
        else:
            return "", False

    def armar_lista_de_grupos(self):
        """Permite completra el treeview31 con los grupos habilidatos."""
        self.lista_grupos = []
        resultado = GrupoDeResolucion.select()
        for grupo in resultado:
            if self.clasificacion_problema in grupo.clasificaciones:
                self.lista_grupos.append(grupo)
        # Armamos las cabeceras de la lista de grupos
        titulos = ["Numero", "Nombre"]
        for pos, titulo in enumerate(titulos):
            add_find_column(titulo, pos, self.tree_resultado)
        self.find_list = gtk.ListStore(str, str)
        self.tree_resultado.set_model(self.find_list)
        #self.tree_resultado.grab_focus()
        # Completamos con los grupos
        for grupo in self.lista_grupos:
            self.find_list.append([str(grupo.id), grupo.nombre])

    def observacion_valida(self):
        """Valida el campo Observaciones.

        Este campo es un dato obligatorio, tanto para la derivacion como para
        el cierre de un reclamo.

        Keyword arguments:
        None
        """
        obs = self.observaciones.get_buffer()
        start = obs.get_start_iter()
        end = obs.get_end_iter()
        if obs.get_text(start, end) != "":
            return obs.get_text(start, end), True
        else:
            msj = "Observacion no puede ser nulo en esta operacion."
            print msj
            msj_error = MensajeDeError(msj, self.padre.window)
            msj_error.run()
            return "", False

    def close_ticket(self, widget=None):
        """CDU03 Cerrar ticket.

        Cerrará el ticket almacenando la fecha y hora actual.
        """
        obs, bandera = self.observacion_valida()
        if bandera:
            texto = "¿Está seguro que desea cerrar el reclamo?"
            msj = MensajeDeAdvertencia(texto, self.padre.window)
            if msj.msj.run() == gtk.RESPONSE_YES:
                print "Cerrando reclamo..."
                fecha_cierre = datetime.now()
                self.padre.mesa_de_ayuda.cerrar_ticket(self.padre.usuario_logueado,
                        obs,
                        fecha_cierre,
                        self.ticket)
                self.limpiar_campos()
                self.padre.wTree.get_widget("hbox41").hide()
                self.padre.wTree.get_widget("hbox53").hide()
                self.padre.wTree.get_widget("hbox58").hide()
                msj.msj.destroy()
                fecha = fecha_cierre.strftime("%d-%m-%Y %H:%M:%S")
                texto = ("El ticket nro %d" % self.ticket.numero_ticket,
                    "se cerro correctamente a las %s" % fecha)
                notificacion = MensajeDeNotificacion("\n".join(texto), self.padre.window)
                if notificacion.msj.run() == -5:
                    notificacion.msj.destroy()

            else:
                msj.msj.destroy()

    def limpiar_campos(self):
        """Limpia los campos de entrada"""
        lista_widget =(self.entry_legajo_empleado,
                self.entry_apellido_empleado,
                self.entry_nombre_empleado,
                self.entry_codigo_clasificacion,
                self.entry_nombre_clasificacion)
        for widget in lista_widget:
            widget.set_text('')
        self.entry_descripcion.get_buffer().set_text('')
        self.observaciones.get_buffer().set_text('')

    def close(self, widget):
        close(self.padre.window)
